package com.wisdytech.linkdcs.system.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.pagehelper.PageInfo;
import com.wisdytech.common.bean.Filter;
import com.wisdytech.common.bean.StandardResult;
import com.wisdytech.common.constants.CommonConstants;
import com.wisdytech.common.enums.UserStatus;
import com.wisdytech.common.exception.ServiceException;
import com.wisdytech.common.handler.BaseService;
import com.wisdytech.common.session.UserSession;
import com.wisdytech.common.shiro.MyShiroRealm;
import com.wisdytech.common.utils.BaseUtil;
import com.wisdytech.common.utils.MD5Util;
import com.wisdytech.linkdcs.system.dao.ISysUserDao;
import com.wisdytech.linkdcs.system.dao.ISysUserRoleDao;
import com.wisdytech.linkdcs.system.model.SysUser;
import com.wisdytech.linkdcs.system.model.SysUserRole;
import com.wisdytech.linkdcs.system.service.ISystemUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 
 * <p>
 * ClassName: SystemUserServiceImpl.java
 * </p>
 * <p>
 * Description: 
 * </p>
 * <p>
 * Author: kongming
 * </p>
 * <p>
 * Date: 2017-9-13
 * </p>
 */
@Service("systemUserService")
@Transactional
public  class SystemUserServiceImpl extends BaseService<ISysUserDao, SysUser> implements ISystemUserService {
    @Resource
    private ISysUserDao sysUserDao;
    
    @Resource
    private ISysUserRoleDao sysUserRoleDao;
    
    @Override
    public StandardResult addSysUser(SysUser sysUser, UserSession userSession) {
      EntityWrapper<SysUser> ew = new EntityWrapper<>();
      //验证用户名的唯一性
      List<SysUser> userNameList;
      userNameList = sysUserDao.selectPage(new Page<SysUser>(1, 1), ew.eq("username", sysUser.getUsername()).eq("del_flag", CommonConstants.DEL_FLAG));
      if (!userNameList.isEmpty()) {
          return StandardResult.getFailResult(CommonConstants.USER_NAME);
      }
      //验证工号的唯一性
      List<SysUser> userWorkList;
      EntityWrapper<SysUser> ew1 = new EntityWrapper<>();
      userWorkList = sysUserDao.selectPage(new Page<SysUser>(1, 1), ew1.eq("work_no", sysUser.getWorkNo()).eq("del_flag", CommonConstants.DEL_FLAG));
      if (!userWorkList.isEmpty()) {
          return StandardResult.getFailResult(CommonConstants.USER_WORK_NO);
      }
      sysUser.setPkId(BaseUtil.getUUID());
      sysUser.setPassword(MD5Util.getDigest(sysUser.getPassword()));
      sysUser.setDelFlag(CommonConstants.DEL_FLAG);
      sysUser.setCreateDate(new Date());
      SysUser currentUser = BaseUtil.getCurrentUser();
      if(currentUser!=null) {
    	  sysUser.setCreateUser(currentUser.getPkId());
      }
      //保存到关联表中
      SysUserRole sysUserRole = new SysUserRole();
      sysUserRole.setUserId(sysUser.getPkId());
      sysUserRole.setRoleId(sysUser.getRoleId());
      sysUserRoleDao.insert(sysUserRole);
      
      int count;
      count =  sysUserDao.insert(sysUser);
      if (count <= 0) {
          throw new ServiceException("新增失败");
      }
      return StandardResult.getSuccessResult();
        
    }

    @Override
    public StandardResult updateUser(SysUser sysUser) {
        //验证工号的唯一性
        List<SysUser> userWorkList;
        EntityWrapper<SysUser> ew1 = new EntityWrapper<>();
        userWorkList = sysUserDao.selectPage(new Page<SysUser>(1, 1), ew1.eq("work_no", sysUser.getWorkNo()).eq("del_flag", CommonConstants.DEL_FLAG).ne("pk_id",sysUser.getPkId()));
        if (!userWorkList.isEmpty()) {
            return StandardResult.getFailResult(CommonConstants.USER_WORK_NO);
        }
        if(StringUtils.isNotBlank(sysUser.getRoleId())){
            //更新用户角色
            EntityWrapper<SysUserRole> userRoleWrapper =new EntityWrapper<>();
            //更新角色
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getPkId());
            sysUserRole.setRoleId(sysUser.getRoleId());
            sysUserRoleDao.update(sysUserRole, userRoleWrapper.eq("user_id", sysUser.getPkId()));
        }
        SysUser user = sysUserDao.selectById(sysUser.getPkId());

        //校验是否更新了用户名和密码
        boolean updateUserNameOrPwd = false;
        if(!user.getPassword().equals(sysUser.getPassword()))
            updateUserNameOrPwd = true;
        if(!user.getUsername().equals(sysUser.getUsername()))
            updateUserNameOrPwd = true;
        if (!user.getPassword().equals(sysUser.getPassword())) {
            //用户更改了密码
            sysUser.setPassword(MD5Util.getDigest(sysUser.getPassword()));
        }else {
            sysUser.setPassword(sysUser.getPassword());
        }
        EntityWrapper<SysUser> ew = new EntityWrapper<>();
        int count;
        count = sysUserDao.update(sysUser, ew.eq("pk_id", sysUser.getPkId()));
        if (count <= 0) {
            return StandardResult.getFailResult("修改失败");
        }
        //修改用户时删除权限缓存
        RealmSecurityManager securityManager =
                (RealmSecurityManager) SecurityUtils.getSecurityManager();
        MyShiroRealm myShiroRealm = (MyShiroRealm)securityManager.getRealms().iterator().next();
        Cache<Object, AuthorizationInfo> cache = myShiroRealm.getAuthorizationCache();
        for (Object o: cache.keys()) {
            SysUser u = (SysUser)((SimplePrincipalCollection)o).getPrimaryPrincipal();
            if(sysUser.getPkId().equals(u.getPkId())) {
                myShiroRealm.getAuthorizationCache().remove(((SimplePrincipalCollection)o));
            }
        }

        /**
         * 修改用户名和密码， 剔除该用户session信息
         */
        if(updateUserNameOrPwd) {
            SessionsSecurityManager sessionSecurityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();
            DefaultSessionManager sessionManager = (DefaultSessionManager) sessionSecurityManager.getSessionManager();
            Collection<Session> sessions=
                    sessionManager.getSessionDAO().getActiveSessions();//获取已登录的用户session列表
            for (Session session : sessions) {
                //当前session 跳出
                if(SecurityUtils.getSubject().getSession().getId().equals(session.getId())) {
                    continue;
                }
                SysUser sessionUser= (SysUser)session.getAttribute("user");
                if(null != sessionUser) {
                    if(sysUser.getPkId().equals(sessionUser.getPkId())){
                        sessionManager.getSessionDAO().delete(session);
                    }
                }
            }
        }

        return StandardResult.getSuccessResult();
    }

    @Override

    public StandardResult deleteUserById(String ids) {
        SysUser sysUser = new SysUser();
        for (String id : ids.split(",")) {
           EntityWrapper<SysUser> ew = new EntityWrapper<>();
           sysUser = sysUserDao.selectById(id);
           sysUser.setDelFlag(CommonConstants.DEL_FLAG_TRUE);
           int count = sysUserDao.update(sysUser, ew.eq("pk_id", id));
           if (count <=0) {
               throw new ServiceException("删除失败");
           }
           int counts = sysUserRoleDao.deleteRoleIdById(sysUser.getPkId());
           if (counts <=0) {
               throw new ServiceException("删除角色与用户关联失败");
           }
         }
        
        
        return StandardResult.getSuccessResult();
    }

    @Override
    public StandardResult enableUserById(String ids) {
        for (String id : ids.split(",")) {
            SysUser user;
           user = sysUserDao.selectById(id);
           //0代表禁用 1代表启用
//           if (UserStatus.DISABLE.getCode().equals(user.getEnabled())) {
               user.setEnabled(UserStatus.ENABLE.getCode());
               user.setUpdateDate(new Date());
               user.setUpdateUser(user.getUsername());
               int count = sysUserDao.updateById(user);
               if (count <= 0) {
                   throw new ServiceException("启用失败"); 
               }
//           }else {
//               return StandardResult.getFailResult(UserStatus.ENABLE.getContext());
//           }
        }
        return StandardResult.getSuccessResult();
    }

    @Override
    public StandardResult disableUserById(String ids) {
        for (String id : ids.split(",")) {
            SysUser user;
            user = sysUserDao.selectById(id);
            SysUser currentUser = BaseUtil.getCurrentUser();
            if(user.getPkId().equals(currentUser.getPkId())) {
                return StandardResult.getFailResult("禁用的用户中请不要包含自己");
            }
            user.setEnabled(UserStatus.DISABLE.getCode());
            user.setUpdateDate(new Date());
            user.setUpdateUser(user.getUsername());
            int count = sysUserDao.updateById(user);
            if (count<=0){
               throw new ServiceException("禁用失败");
            }
        }
        //处理session
        SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();
        DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
        Collection<Session> sessions=
                sessionManager.getSessionDAO().getActiveSessions();//获取已登录的用户session列表

        for (String id : ids.split(",")) {
            for(Session session : sessions) {
                //清楚该用户以前登录保存的session
                SysUser sessioUser= (SysUser)session.getAttribute("user");
                if(null != sessioUser) {
                    if(id.equals(sessioUser.getPkId())){
                        sessionManager.getSessionDAO().delete(session);
                    }
                }


            }
        }
        return StandardResult.getSuccessResult();
    }

    @Override
    public SysUser getUserByName(String loginName) {
        SysUser sysUser = new SysUser();
        sysUser.setUsername(loginName);
        return sysUserDao.getUserByName(loginName);
    }

    @Override
    public PageInfo<SysUser> listSysUsers(String username, String truename, String workNo, Filter filter) {
        
        Map<String,String> params =new HashMap<String,String>();
        params.put("username", username);
        params.put("truename", truename);
        params.put("work_no", workNo);
        
        
        List<SysUser> lists =
                super.beforeList(ISysUserDao.class, filter).selectAllUsers(params);
        PageInfo<SysUser> userPage=new PageInfo<>(lists);
        return userPage;
    }
    @Override
    public SysUser getUserById(String id) {
        return sysUserDao.getUserById(id);
    }

    @Override
    public PageInfo<SysUser> getSystemUserList(String search,Filter filter) {
        EntityWrapper<SysUser> ew =new EntityWrapper<>();
        ew.setSqlSelect("pk_id","truename","username");
        if(StringUtils.isNotBlank(search)) {
            ew.like("truename",search);
        }
        ew.eq("del_flag", CommonConstants.DEL_FLAG)
                .orderBy("CREATE_DATE", false);
        //List<SysUser> list = this.beforeList(ISysUserDao.class,filter).selectList(ew);
        List<SysUser> list = sysUserDao.selectList(ew);
        PageInfo<SysUser> page = new PageInfo<>(list);
        return page;
    }

	@Override
	public PageInfo<SysUser> getAllUserLists(String username, String truename, String workNo, Filter filter) {
        
        Map<String,String> params =new HashMap<String,String>();
        params.put("username", username);
        params.put("truename", truename);
        params.put("work_no", workNo);
        
        
        List<SysUser> lists =
                super.beforeList(ISysUserDao.class, filter).getAllUserLists(params);
        PageInfo<SysUser> userPage=new PageInfo<>(lists);
        return userPage;
	}
}
